package com.share.exception;

import com.share.common.enums.HttpStatusEnum;
import lombok.Getter;

import java.io.Serial;
import java.io.Serializable;
import java.time.Instant;

/**
 * 基础异常类
 */
@Getter
public class BaseException extends RuntimeException implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private final Integer code;
    private final String message;
    private final Object details;
    private final Instant timestamp;
    private final HttpStatusEnum status;

    public BaseException(Object details, Instant timestamp, HttpStatusEnum status) {
        super(status.getMessage());
        this.details = details;
        this.timestamp = timestamp;
        this.status = status;
        this.code = status.getCode();
        this.message = status.getMessage();
    }


    public BaseException(HttpStatusEnum status, String message, Object details, Instant timestamp) {
        super(message);
        this.status = status;
        this.code = status.getCode();
        this.message = message;
        this.details = details;
        this.timestamp = timestamp;
    }

    public BaseException(HttpStatusEnum status, String message, Instant timestamp) {
        super(message);
        this.status = status;
        this.code = status.getCode();
        this.message = message;
        this.details = null;
        this.timestamp = timestamp;
    }

    public BaseException(HttpStatusEnum status, String message, Object details, Instant timestamp, Object... args) {
        super(String.format(message, args));
        this.status = status;
        this.code = status.getCode();
        this.details = details;
        this.timestamp = timestamp;
        this.message = String.format(message, args);
    }

    public BaseException(HttpStatusEnum status, Throwable cause, Object details, Instant timestamp) {
        super(status.getMessage(), cause);
        this.status = status;
        this.code = status.getCode();
        this.message = status.getMessage();
        this.details = details;
        this.timestamp = timestamp;
    }

    public BaseException(HttpStatusEnum status, String message, Throwable cause, Object details, Instant timestamp) {
        super(message, cause);
        this.status = status;
        this.code = status.getCode();
        this.message = message;
        this.details = details;
        this.timestamp = timestamp;
    }

    public BaseException(int code, String message, Object details, Instant timestamp) {
        super(message);
        this.code = code;
        this.message = message;
        this.status = HttpStatusEnum.getByCode(code);
        this.details = details;
        this.timestamp = timestamp;
    }

    public BaseException(int code, String message, Throwable cause, Object details, Instant timestamp) {
        super(message, cause);
        this.code = code;
        this.message = message;
        this.status = HttpStatusEnum.getByCode(code);
        this.details = details;
        this.timestamp = timestamp;
    }

    @Override
    public String toString() {
        return String.format("BaseException{code=%d, message='%s', status=%s}",
                code, message, status);
    }

    public String toLogString() {
        return String.format("[%d]%s - %s", code, status.name(), message);
    }
}